package com.mallcai.bigdata.ladon.service.export.impl.handler;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.mallcai.bigdata.ladon.client.export.ExportStrategy;
import com.mallcai.bigdata.ladon.client.vo.ReportDataVO;
import com.mallcai.bigdata.ladon.service.export.impl.ExportContext;
import com.mallcai.bigdata.ladon.tools.FileUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVPrinter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * described :生成Csv类型的文件
 *
 * @author CaKeDou
 * @date 2019-09-26 21:52
 * Modify:
 */
@Slf4j
@Component
@Order(600)
public class GenCsvHandler extends AbstractExportPreHandler {

    @Override
    public void preInternal(ExportContext exportContext) {
        if (exportContext.getExportStrategy().getFileType() != ExportStrategy.ExportFileTypeEnum.CSV) {
            return;
        }
        Writer out = null;
        OutputStreamWriter osw = null;
        CSVPrinter printer = null;
        try {
            FileUtil.createOrExistsFile(exportContext.getFilePath());
            File csvFile = new File(exportContext.getFilePath());
            osw = new OutputStreamWriter(new FileOutputStream(csvFile), "UTF-8");
            //写入BOM头,防止用Excel打开CSV文件时出现乱码
            osw.write(new String(new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF}));
            out = new BufferedWriter(osw, 1024);
            ReportDataVO reportDataVO = exportContext.getTargetData();
            List<String> columnNames = reportDataVO.getColumns().stream().map(t ->t.getName()).collect(Collectors.toList());
            List<String> columnShowNames = reportDataVO.getColumns().stream().map(t -> StringUtils.isNotBlank(t.getShowName()) ? t.getShowName() : t.getName()).collect(Collectors.toList());
            final String[] fileHeader = columnShowNames.toArray(new String[0]);
            CSVFormat format = CSVFormat.DEFAULT.withHeader(fileHeader);
            printer = new CSVPrinter(out, format);

            for (Map<String, Object> oneRow : reportDataVO.getRows()) {
                List<String> oneRecord = new ArrayList<>();
                for (String key : columnNames) {
                    for (Map.Entry<String, Object> oneEntry : oneRow.entrySet()) {
                        if (StringUtils.equals(oneEntry.getKey(), key)) {
                            oneRecord.add(String.valueOf(oneEntry.getValue()));
                            break;
                        }
                    }
                }
                printer.printRecord(oneRecord);
            }
            printer.flush();
            printer.close();
        } catch (Throwable e) {
            log.error("生成CSV文件异常", e);
            throw new BusinessException("生成CSV文件异常");
        } finally {
            try {
                //先打开的流后关闭,最后打开的流最先关闭
                if (printer != null) {
                    printer.close();
                }
                if (out != null) {
                    out.close();
                }
                if (osw != null) {
                    osw.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
